<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
</head>
<body>
<script>
    /*
        0.属性
        Object.defineProperty(obj,'filed',{
            writable: ,
            enumerable:,
            writable:,
            value,
        })
        
        // 1,数据属性
        configurable:表示属性是否可以通过 delete 删除并重新定义，是否可以修改它的特 性，以及是否可以把它改为访问器属性。默认情况下，所有直接定义在对象上的属性的这个特 性都是 true，
        enumerable: 表示属性是否可以通过 for-in 循环返回。默认情况下，所有直接定义在对 象上的属性的这个特性都是 true，
        writable:   表示属性的值是否可以被修改。默认情况下，所有直接定义在对象上的属性的 这个特性都是 true
        value:      包含属性实际的值。这就是前面提到的那个读取和写入属性值的位置。这个特性 的默认值为 undefined
        
        //1.1 数据属性说明
        -   一个属性被定义configurable:false后,就不可以再变回可配置的了
        -   再次调用Object.defineProperty()并修改任何非writable属性都会报错
        -   前面3个值默认为true
        
        // 2访问器属性
        configurable:表示属性是否可以通过 delete 删除并重新定义，是否可以修改它的特 性，以及是否可以把它改为访问器属性。默认情况下，所有直接定义在对象上的属性的这个特 性都是 true，
        enumerable: 表示属性是否可以通过 for-in 循环返回。默认情况下，所有直接定义在对 象上的属性的这个特性都是 true，
        get:        获取函数，在读取属性时调用。默认值为 undefined。
        set:        设置函数，在写入属性时调用。默认值为 undefined。
     */
    
    /*
        3.想一下作业
        let obj = {
            name:'张三',
            age:14,
            level:1,
        }
        1.age不可修改,如果age>=18才显示name,否则显示未成年
        2.name不可修改
        3.level可以修改,如果level+age>=18,也同样显示name
     */
    let obj = {
        name:'张三',
        age:14,
        level:1,
    }
    Object.defineProperty(obj,'age',{
        get(){
            if(this.age+this.level<18){
                return '未成年'
            }
        },
    })
    Object.defineProperty(obj,'name',{
        value:'张三'
        // 同时设置数据属性和访问器属性会报错
      /*  get(){
            return '你好'
        }*/
    })
    // delete obj.name
    obj.name = '李四'
    console.log(obj.name)
    
    // 2.读取属性的特性    Object.getOwnPropertyDescriptor
    console.log(Object.getOwnPropertyDescriptor(obj,'name'))
    /*
        {value: "李四", writable: true, enumerable: true, configurable: true}
     */
</script>
</body>
</html>